import tkinter as tk
from tkinter import ttk, messagebox
import re
import requests
import concurrent.futures
import threading
import time

# 规范化 MAC 地址格式
def normalize_mac(mac):
    mac = mac.strip().lower()
    if re.match(r'^[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}$', mac):
        mac = mac.replace('-', '')
        return ':'.join([mac[i:i + 2] for i in range(0, 12, 2)])
    if re.match(r'^[0-9a-f]{4}\.[0-9a-f]{4}\.[0-9a-f]{4}$', mac):
        mac = mac.replace('.', '')
        return ':'.join([mac[i:i + 2] for i in range(0, 12, 2)])
    if re.match(r'^([0-9a-f]{2}-){5}[0-9a-f]{2}$', mac):
        return mac.replace('-', ':')
    if re.match(r'^([0-9a-f]{2}:){5}[0-9a-f]{2}$', mac):
        return mac
    return None

# 判断是否为随机地址
def is_random_mac(mac):
    try:
        first_byte = int(mac.split(':')[0], 16)
        return bool(first_byte & 0b00000010)
    except:
        return False

# 获取厂商名称
def get_vendor(mac, retries=3, delay=1):
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                      "AppleWebKit/537.36 (KHTML, like Gecko) "
                      "Chrome/91.0.4472.124 Safari/537.36"
    }

    for attempt in range(retries):
        try:
            url = f"https://api.macvendors.com/{mac}"
            response = requests.get(url, headers=headers, timeout=5)
            if response.status_code == 200:
                return response.text.strip()
            else:
                time.sleep(delay)  # 短暂等待后重试
        except requests.RequestException:
            time.sleep(delay)

    return "查询失败"

# 异步分析任务（后台线程）
def analyze_in_background(macs, output_text):
    results = []

    def process_mac(raw_mac):
        mac = normalize_mac(raw_mac)
        if not mac:
            return f"{raw_mac.strip()} → ❌ 无效格式\n"
        if is_random_mac(mac):
            return f"{mac} → ⚠️ 随机地址\n"
        else:
            vendor = get_vendor(mac)
            return f"{mac} → ✅ 物理地址，厂商：{vendor}\n"

    with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
        future_to_mac = {executor.submit(process_mac, mac): mac for mac in macs}
        for future in concurrent.futures.as_completed(future_to_mac):
            result = future.result()
            results.append(result)

    # 主线程更新 UI
    def update_ui():
        output_text.config(state=tk.NORMAL)
        output_text.delete("1.0", tk.END)
        for line in results:
            output_text.insert(tk.END, line)
        output_text.config(state=tk.DISABLED)

    output_text.after(0, update_ui)

# 主分析函数（触发按钮）
def analyze_macs():
    output_text.config(state=tk.NORMAL)
    output_text.delete("1.0", tk.END)

    raw_lines = input_text.get("1.0", tk.END).strip().splitlines()
    raw_count = len([line for line in raw_lines if line.strip()])

    # 规范化后去重
    seen = set()
    normalized_macs = []
    for line in raw_lines:
        mac = normalize_mac(line)
        if mac and mac not in seen:
            seen.add(mac)
            normalized_macs.append((line.strip(), mac))

    unique_count = len(normalized_macs)

    original_count_var.set(f"输入总数: {raw_count}")
    unique_count_var.set(f"去重后: {unique_count}")

    if not normalized_macs:
        messagebox.showwarning("输入为空", "请输入至少一个有效的 MAC 地址")
        return

    def process_mac(original, mac):
        if is_random_mac(mac):
            return f"{original} → ⚠️ 随机地址\n"
        else:
            vendor = get_vendor(mac)
            return f"{original} → ✅ 物理地址，厂商：{vendor}\n"

    results = []
    for original, mac in normalized_macs:
        result = process_mac(original, mac)
        results.append(result)

    for line in results:
        output_text.insert(tk.END, line)

    output_text.config(state=tk.DISABLED)

# =================== UI 初始化 =====================
root = tk.Tk()
root.title("MAC 地址检测工具 -- 作者：ZionLoh，开源地址：https://gitee.com/zionloh")
root.geometry("800x600")
root.minsize(600, 400)

style = ttk.Style()
style.theme_use("clam")

# 自适应布局
root.grid_columnconfigure(0, weight=1)
root.grid_columnconfigure(1, weight=1)
root.grid_rowconfigure(1, weight=1)
root.grid_rowconfigure(3, weight=2)
for i in range(5):
    root.grid_rowconfigure(i, weight=1)

input_label = tk.Label(root, text="请输入 MAC 地址（每行一个）:")
input_label.grid(row=0, column=0, columnspan=2, sticky="w", padx=10, pady=(10, 0))

input_text = tk.Text(root, height=10, wrap=tk.WORD)
input_text.grid(row=1, column=0, columnspan=2, sticky="nsew", padx=10, pady=5)

analyze_button = tk.Button(root, text="分析 MAC 地址", command=analyze_macs)
analyze_button.grid(row=1, column=2, sticky="e", padx=10)

output_label = tk.Label(root, text="结果:")
output_label.grid(row=2, column=0, columnspan=2, sticky="w", padx=10)

output_text = tk.Text(root, height=10, wrap=tk.WORD, state=tk.DISABLED)
output_text.grid(row=3, column=0, columnspan=3, sticky="nsew", padx=10, pady=5)

stats_frame = tk.Frame(root)
stats_frame.grid(row=4, column=0, columnspan=3, sticky="ew", padx=10, pady=(5, 10))

original_count_var = tk.StringVar()
unique_count_var = tk.StringVar()

original_label = tk.Label(stats_frame, textvariable=original_count_var, anchor="w")
original_label.pack(side="left", padx=(0, 20))

unique_label = tk.Label(stats_frame, textvariable=unique_count_var, anchor="w")
unique_label.pack(side="left")

# 设置窗口图标
'''
try:
    root.iconbitmap("zl.ico")
except Exception as e:
    print(f"图标设置失败: {e}")
'''

# 设置居中显示
def center_window(window):
    window.update_idletasks()
    w = window.winfo_width()
    h = window.winfo_height()
    ws = window.winfo_screenwidth()
    hs = window.winfo_screenheight()
    x = (ws // 2) - (w // 2)
    y = (hs // 2) - (h // 2)
    window.geometry(f'{w}x{h}+{x}+{y}')

root.update()
center_window(root)

# 展示UI界面
root.mainloop()
